/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package org.me.dao;

import java.util.List;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;


public class GenericDAO<T> implements InterfaceDAO<T>{
   private EntityManager em = FabricaDAO.obterFabrica().createEntityManager();

    public GenericDAO() {
    }

    public boolean iniciarTransacao() {
        try {
            if (em.getTransaction().isActive()) {
                return true;
            }
            em.getTransaction().begin();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public boolean confirmarTransacao() {
        try {
            em.getTransaction().commit();
            return true;
        } catch (EntityExistsException e) {
            return false;
        }
    }

    public boolean desfazerTransacao() {
        try {
            em.getTransaction().rollback();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public boolean criar(T o) {
        try {
            this.iniciarTransacao();
            em.persist(o);
            this.confirmarTransacao();
            return true;
        } catch (Exception e) {
            if (em.isOpen()) {
                this.desfazerTransacao();
            }
            return false;
        }
    }

    @Override
    public boolean excluir(T o) {
        try {
            this.iniciarTransacao();
            em.remove(em.merge(o));
            this.confirmarTransacao();
            return true;
        } catch (Exception e) {
            if (em.isOpen()) {
                this.desfazerTransacao();
            }
            return false;
        }
    }

    @Override
    public boolean atualizar(T o) {
        try {
            this.iniciarTransacao();
            em.merge(o);
            this.confirmarTransacao();
            return true;
        } catch (Exception e) {
            if (em.isOpen()) {
                this.desfazerTransacao();
            }
            return false;
        }
    }

    @Override
    public T obter(Class<T> classe, Object id) {
        String namedQuery = classe.getSimpleName() + ".findById";
        TypedQuery<T> q = em.createNamedQuery(namedQuery, classe);
        q.setParameter("id", id);
        T o = q.getSingleResult();
        return o;
    }

    @Override
    public List<T> obterTodos(Class<T> classe) {
        String query = classe.getSimpleName() + ".findAll";
        TypedQuery<T> q = em.createNamedQuery(query, classe);
        return q.getResultList();
    }

    /**
     * @return the entityManager
     */
    public EntityManager getEntityManager() {
        return em;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        if (this.em != null && this.em.isOpen()) {
            this.em.close();
        }
    }
}
